package com.ctvit.cch.core.task;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ctvit.cch.ai.pojo.dto.GenerateShotDTO;
import com.ctvit.cch.ai.pojo.vo.GenerateShotVO;
import com.ctvit.cch.ai.service.ILlmService;
import com.ctvit.cch.core.enums.GenerateStatusEnum;
import com.ctvit.cch.core.pojo.domain.CreativeShotDesign;
import com.ctvit.cch.core.pojo.domain.CreativeShotFrame;
import com.ctvit.cch.core.pojo.vo.creative.CreativeScriptSceneListVO;
import com.ctvit.cch.core.service.ICreativeScriptDesignService;
import com.ctvit.cch.core.service.ICreativeScriptSceneService;
import com.ctvit.cch.core.service.ICreativeShotDesignService;
import com.ctvit.cch.core.service.ICreativeShotFrameService;
import com.ctvit.cch.core.service.ICreativeTopicService;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

/**
 * 分镜设计任务
 *
 * @author heyingcheng
 * @date 2025/10/31
 */
@Slf4j
@Component("creativeShotDesignTask")
@ConditionalOnProperty(name = "cch.core.task.shot-design.enabled", havingValue = "true")
public class CreativeShotDesignTask implements SchedulingConfigurer {

    private static final String CRON_EXPRESSION = "0/5 * * * * ?";

    @Resource
    private ICreativeTopicService creativeTopicService;

    @Resource
    private ICreativeScriptDesignService creativeScriptDesignService;

    @Resource
    private ICreativeScriptSceneService creativeScriptSceneService;

    @Resource
    private ICreativeShotDesignService creativeShotDesignService;

    @Resource
    private ICreativeShotFrameService creativeShotFrameService;

    @Resource
    private ILlmService llmService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(this::execute, triggerContext -> {
            CronTrigger trigger = new CronTrigger(CRON_EXPRESSION);
            return trigger.nextExecution(triggerContext);
        });
    }

    public void execute() {
        log.debug("执行分镜设计任务-开始");

        List<CreativeShotDesign> shotDesignList = creativeShotDesignService
                .list(new LambdaQueryWrapper<CreativeShotDesign>()
                        .eq(CreativeShotDesign::getGenerateStatus, GenerateStatusEnum.QUEUED.name())
                        .orderByAsc(CreativeShotDesign::getUpdateTime)
                        .last("LIMIT 10"));

        for (CreativeShotDesign shotDesign : shotDesignList) {
            try {
                generateShotDesign(shotDesign);
            } catch (Exception e) {
                log.error("生成场景分镜任务异常, shotId:[{}]", shotDesign.getShotId(), e);
            }
        }

        log.debug("执行分镜设计任务-结束");
    }

    private boolean generateShotDesign(CreativeShotDesign shotDesign) {
        // 更新选题和脚本分镜状态为ING
        final String topicId = shotDesign.getTopicId();
        final String scriptId = shotDesign.getScriptId();
        final String shotId = shotDesign.getShotId();
        creativeShotDesignService.updateGenerateStatus(topicId, scriptId, shotId, GenerateStatusEnum.ING.name());

        // 按场景列表ID和场景状态查询场景列表
        List<CreativeScriptSceneListVO> scriptSceneList = creativeScriptSceneService.listByShotStatus(scriptId,
                GenerateStatusEnum.QUEUED.name());
        for (CreativeScriptSceneListVO scriptSceneListVo : scriptSceneList) {
            try {
                generateSceneShot(shotId, scriptSceneListVo);
            } catch (Exception e) {
                log.error("生成场景分镜任务异常, sceneId:[{}]", scriptSceneListVo.getSceneId(), e);
            }
        }

        // 完成分镜设计
        return creativeShotDesignService.completeGenerateDesign(topicId, scriptId, shotId);
    }

    private boolean generateSceneShot(String shotId, CreativeScriptSceneListVO scriptSceneListVo) {
        String sceneId = scriptSceneListVo.getSceneId();
        creativeScriptSceneService.updateShotStatus(sceneId, GenerateStatusEnum.QUEUED.name(),
                GenerateStatusEnum.ING.name());

        try {
            GenerateShotDTO generateShotDTO = new GenerateShotDTO();
            generateShotDTO.setSceneIndex(scriptSceneListVo.getSceneIndex());
            generateShotDTO.setSceneName(scriptSceneListVo.getSceneName());
            generateShotDTO.setSceneDuration(scriptSceneListVo.getSceneDuration());
            generateShotDTO.setSceneDescription(scriptSceneListVo.getSceneDescription());
            generateShotDTO.setEventDescription(scriptSceneListVo.getEventDescription());
            generateShotDTO.setCharacters(
                    JSON.toJSONString(CollectionUtils.emptyIfNull(scriptSceneListVo.getCharacters())));
            generateShotDTO.setCharacterDialogue(scriptSceneListVo.getCharacterDialogue());
            generateShotDTO.setSidebarContent(scriptSceneListVo.getSidebarContent());

            List<GenerateShotVO> scripShots = llmService.generateShot(generateShotDTO);

            // 将GenerateShotVO列表转换为CreativeShotFrame集合
            List<CreativeShotFrame> shotFrames = new ArrayList<>();
            int size = scripShots.size();
            for (int i = 0; i < size; i++) {
                GenerateShotVO scriptShot = scripShots.get(i);

                CreativeShotFrame entity = new CreativeShotFrame();
                entity.setShotId(shotId);
                entity.setSceneId(sceneId);
                entity.setScriptId(scriptSceneListVo.getScriptId());
                entity.setTopicId(scriptSceneListVo.getTopicId());
                entity.setSceneIndex(scriptSceneListVo.getSceneIndex());
                entity.setFrameIndex(i + 1);
                entity.setFrameType(scriptShot.getShotType());
                entity.setFrameDescription(scriptShot.getShotDescription());
                entity.setFrameDuration(scriptShot.getShotDuration());
                entity.setFrameDialogue(scriptShot.getShotDialogue());
                entity.setFrameNarration(scriptShot.getShotNarration());
                entity.setFrameSoundEffect(scriptShot.getShotSoundEffect());
                entity.setRemarks(scriptShot.getRemarks());

                shotFrames.add(entity);
            }

            // 批量保存到数据库
            if (CollectionUtils.isNotEmpty(shotFrames)) {
                creativeShotFrameService.saveBatch(shotFrames);
            }
        } catch (Exception e) {
            log.error("生成场景分镜任务异常, sceneId:[{}]", sceneId, e);
            creativeScriptSceneService.updateShotStatus(sceneId, GenerateStatusEnum.ING.name(),
                    GenerateStatusEnum.FAILURE.name());
            return false;
        }

        return creativeScriptSceneService.updateShotStatus(sceneId, GenerateStatusEnum.ING.name(),
                GenerateStatusEnum.SUCCESS.name());
    }

}
